51单片机之模拟IIC总线 您所在的位置:网站首页 platformio 51单片机 51单片机之模拟IIC总线

51单片机之模拟IIC总线

2022-12-19 09:05| 来源: 网络整理| 查看: 265

目录

前言

辅助函数

相关信号函数

起始信号

停止信号

接收应答函数

发送应答信号

应答信号

非应答信号

发送/接收一个字节数据

发送一字节数据

接收一字节数据

应用

IIC级联

最后

前言

        IIC为两线式串行总线,其用于主设备与从设备之间的通信,且任一时刻只能有一台主设备。网上关于IIC的详细说明很多,故本文不打算从介绍IIC入手,直接进行程序说明。

        此外,由于不同的从设备的控制方法不同,鄙人不才,想不到一个比较完美的方法将不同的设备在程序上进行统一,因此,本文章仅介绍IIC的基本信号产生的函数,还望读者谅解。如对设备在程序上的统一,有好办法的读者,还请赐教!

        文章中程序使用的单片机为STC15系列的单片机,所用的时钟频率为24MHz。但是它是适用51系列的单片机的,因其程序编写过程大同小异,故读者可在此基础上适当修改,以适用读者所用的芯片。

辅助函数

在IIC中,当SCL为高电平时,SDA上电平的变化将代表着相关的操作,为防止误触发,每个函数都以SCL为低电平收尾。

/************************************************************************ 本文件为IIC的基本信号集合(作为主机),就目前测试,适合在各个频率下工作, 针对不同的频率,仅需适当调整IIC延时的循环次数即可 每个信号中都以SCL低电平为结尾,这样一来可防止信号发送之后在SDA上的电 平变化引起误触发 *************************************************************************/ sbit SDA = P0^0; sbit SCL = P0^1;

在IIC适用过程中会涉及到相应信号的延时,在此吾建立了一个专用于IIC延时的函数,如下:

/*仅作为IIC延时,故使其仅作为该文件可以调用的函数,可根据不同的时钟频率调节相应的延时时间*/ static void IIC_Delay() { unsigned char i; for(i = 0;i < 2;i++) //根据不同的时钟频率调整不同的循环次数 { _nop_(); } }

接下来的函数是配置所使用到的引脚的模式以及相关的初始化,如下:

/*IIC初始化,将端口设为准双向输入输出(不设置为推挽模式是因为还需要读取数据,推挽下输入的电平几乎是不变的)*/ void IIC_Init() { P0M0 &= 0xfc; //根据需要调整参数 P0M1 &= 0xfc; //根据需要调整参数 SCL = 0; //将时钟线拉低后,数据线上的变化不会产生影响,防止误触发 SDA = 1; //释放数据线 }

相关信号函数 起始信号

起始信号即在SCL为高电平情况下,SDA由高电平变为低电平

/****IIC起始信号(SCL高电平下SDA的一个下降沿,后以SCL变为低电平收尾)****/ /* ____ / \4.7us ___/ \___ */ void IIC_Start() { SDA = 1; SCL = 1; SDA = 0; SCL = 0; } 停止信号

停止信号即在SCL为高电平情况下,SDA由低电平变为高电平

/****IIC停止信号(SCL高电平下SDA一个上升沿,后以SCL变为低电平收尾)****/ /* _____________ SCL ____/ 4us_____ SDA ______/ \____ */ void IIC_Stop() { SDA = 0; SCL = 1; SDA = 1; SCL = 0; } 接收应答函数

主设备释放SDA总线,将SCL总线置为高电平,接收SDA上的应答信号

/*接收应答信号,若接收到非应答信号,则发送停止信号(SDA低电平表示应答,高电平表示非应答)*/ bit IIC_ReceiveACK() { bit state; SDA = 1; SCL = 1; state = SDA; SCL = 0; if(state) //非应答 { IIC_Stop(); } return state; } 发送应答信号 应答信号

SDA保持低电平,然后将SCL由低电平转为高电平

/*************************发送应答信号函数*************************/ /****应答(SDA保持为低电平)****/ /* ____ SCL _______/ \_____ _____ SDA \____________ */ void IIC_SendACK() { SDA = 0; SCL = 1; IIC_Delay(); //必须延时 SCL = 0; } 非应答信号

SDA保持高电平,然后将SCL由低电平转为高电平

/****非应答(SDA保持为高电平)****/ /* ____ SCL _______/ \_____ _____________ SDA ____/ */ void IIC_SendNACK() { SDA = 1; SCL = 1; IIC_Delay(); SCL = 0; } 发送/接收一个字节数据 发送一字节数据 /****IIC发送一个字节数据(每发送一个字节接收一次应答)****/ void IIC_SendByte(unsigned char dat) { unsigned char i; for(i = 0;i < 8;i++) { SDA = (dat >> 7); SCL = 1; IIC_Delay(); SCL = 0; dat


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有